package com.example.myproject.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.myproject.dto.*;
import com.example.myproject.dto.login.ChangePasswordRequest;
import com.example.myproject.dto.login.LoginRequest;
import com.example.myproject.dto.login.RegisterRequest;
import com.example.myproject.dto.login.VerifyEmailRequest;
import com.example.myproject.exception.BusinessException;
import com.example.myproject.mapper.UserMoneyMapper;
import com.example.myproject.model.User;
import com.example.myproject.mapper.UserMapper;
import com.example.myproject.model.UserMoney;
import com.example.myproject.security.JwtTokenUtil;
import com.example.myproject.service.UserService;
import com.example.myproject.vo.LoginResponse;
import com.example.myproject.vo.SimpleUserInfoVO;
import com.example.myproject.vo.UserInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import com.example.myproject.dto.user.UserInfoDTO;
import com.example.myproject.mapper.TitleMapper;
import com.example.myproject.model.Title;
import com.example.myproject.model.User;
@Service
public class UserServiceImpl implements UserService {

    private static final String EMAIL_TOKEN_KEY = "email:verify:%s";

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private EmailService emailService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private TitleMapper titleMapper;
    @Override
    public Long register(RegisterRequest req) {
        // 参数校验
        if (req.getUserName().length() < 3 || req.getUserName().length() > 20
                || req.getPassword().length() < 8 || req.getPassword().length() > 20) {
            throw new IllegalArgumentException("用户名或密码长度不符合要求");
        }
        // 唯一性校验
        if (userMapper.selectCount(new QueryWrapper<User>().eq("user_name", req.getUserName())) > 0) {
            throw new RuntimeException("用户名已存在");
        }
        if (userMapper.selectCount(new QueryWrapper<User>().eq("email", req.getEmail())) > 0) {
            throw new RuntimeException("邮箱已注册");
        }
        // 保存用户（未验证状态）
        User user = new User();
        user.setUserName(req.getUserName());
        user.setPassword(passwordEncoder.encode(req.getPassword()));
        user.setEmail(req.getEmail());
        //user.setInviteCode(req.getInviteCode());
        user.setEmailVerified(false);
        user.setRole("user");
        user.setUserStatus("active");
       // user.setStatus("active");
        user.setCreatedTime(LocalDateTime.now());
        userMapper.insert(user);
        // 初始化用户资金
        UserMoney userMoney = new UserMoney();
        userMoney.setUserId(user.getUserId());
        userMoney.setPoint(100.0);
        userMoney.setTicket(0.0);
        userMoney.setMagicvalue(100.0);
        userMoneyMapper.insert(userMoney);

        // 生成并存储验证 token
        String token = UUID.randomUUID().toString();
        String redisKey = String.format(EMAIL_TOKEN_KEY, req.getEmail());
        redisTemplate.opsForValue().set(redisKey, token, 15, TimeUnit.MINUTES);

        // 发送验证邮件
        emailService.sendVerificationEmail(req.getEmail(), token);

        return user.getUserId();
    }

    @Override
    public String verifyEmail(VerifyEmailRequest req) {
        String key = String.format(EMAIL_TOKEN_KEY, req.getEmail());
        Object redisToken = redisTemplate.opsForValue().get(key);
        if (redisToken == null || !redisToken.equals(req.getToken())) {
            throw new RuntimeException("验证码无效或已过期");
        }
        // 更新状态
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("email", req.getEmail()));
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        user.setEmailVerified(true);
        userMapper.updateById(user);
        // 删除缓存 key
        redisTemplate.delete(key);
        // 返回 access token
        return jwtTokenUtil.generateAccessToken(user.getUserId(), user.getUserName(), user.getRole(), user.getUserLevel());
    }

    @Override
    public LoginResponse login(LoginRequest req) {
        // 根据用户名或邮箱查用户
        User user = userMapper.selectOne(new QueryWrapper<User>()
                .eq("user_name", req.getUserName()).or().eq("email", req.getUserName()));
        if (user == null || !passwordEncoder.matches(req.getPassword(), user.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }
        if (!Boolean.TRUE.equals(user.getEmailVerified())) {
            throw new RuntimeException("请先完成邮箱验证");
        }
        // 生成令牌
        String access = jwtTokenUtil.generateAccessToken(user.getUserId(), user.getUserName(), user.getRole(), user.getUserLevel());
        String refresh = jwtTokenUtil.generateRefreshToken(user.getUserId(), user.getUserName(), user.getRole(), user.getUserLevel());
        // 构造返回
        LoginResponse resp = new LoginResponse();
        resp.setAccessToken(access);
        resp.setRefreshToken(refresh);
        // 简易用户信息
        SimpleUserInfoVO vo = new SimpleUserInfoVO();
        vo.setUserId(user.getUserId());
        vo.setUserName(user.getUserName());
        vo.setAvatarUrl(user.getAvatar());
        vo.setRole(user.getRole());
        vo.setUserStatus(String.valueOf(user.getUserStatus()));
        vo.setUserLevel(user.getUserLevel());
        resp.setUserInfo(vo);
        return resp;
    }

    @Override
    public UserInfoVO getUserInfo(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        UserInfoVO vo = new UserInfoVO();
        vo.setUserId(user.getUserId());
        System.out.println(user.getUserName());
        vo.setUserName(user.getUserName());
        // 邮箱脱敏
        String email = user.getEmail();
        String masked = email.replaceAll("(?<=.).(?=[^@]*?@)", "*");
        vo.setEmail(masked);
        vo.setAvatarUrl(user.getAvatar());
        vo.setBio(user.getBio());
        vo.setRole(user.getRole());
        vo.setUserStatus(String.valueOf(user.getUserStatus()));
        vo.setCreatedTime(user.getCreatedTime().toString().replace("T", " "));
        return vo;
    }
    @Override
    public UserInfoDTO getUserInfo1(Long userId) {
        // 获取用户基本信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 转换为DTO
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        userInfoDTO.setUserId(user.getUserId());
        userInfoDTO.setUserName(user.getUserName());
        userInfoDTO.setUserStatus(user.getUserStatus());
        userInfoDTO.setRole(user.getRole());
        userInfoDTO.setEmail(user.getEmail());
        userInfoDTO.setUserExperience(user.getUserExperience());
     //   userInfoDTO.setAvatarUrl(user.getAvatarUrl());
        userInfoDTO.setBio(user.getBio());
        userInfoDTO.setTitleId(user.getTitleId());

        userInfoDTO.setAvatar(user.getAvatar());
        userInfoDTO.setEmailVerified(user.getEmailVerified());
        userInfoDTO.setNickName(user.getNickName());
        //vo.setCreatedTime(user.getCreatedTime().toString().replace("T", " "));
        userInfoDTO.setCreatedTime(user.getCreatedTime().toString().replace("T", " "));
        userInfoDTO.setUserLevel(user.getUserLevel());
        userInfoDTO.setPasskey(user.getPasskey());

        // 如果用户有勋章，获取勋章名称
        if (user.getTitleId() != null) {
            Title title = titleMapper.selectById(user.getTitleId());
            if (title != null) {
                userInfoDTO.setTitleName(title.getTitleName());
            }
        }

        return userInfoDTO;
    }
    @Override
    public void updateUserInfo(Long userId, UpdateUserInfoRequest req) {
        // 先从数据库读出原始用户，保留原有 role/status 等字段
        User user = userMapper.selectById(userId);
        if (user == null) {
               throw new RuntimeException("用户不存在");
        }
        if (req.getUserName() != null) user.setUserName(req.getUserName());
        if (req.getAvatarUrl() != null) user.setAvatar(req.getAvatarUrl());
        if (req.getBio() != null) user.setBio(req.getBio());
// 只更新修改过的字段
        userMapper.updateById(user);
    }

    @Override
    public void changePassword(Long userId, ChangePasswordRequest req) {
        User user = userMapper.selectById(userId);
        if (user == null || !passwordEncoder.matches(req.getOldPassword(), user.getPassword())) {
            throw new RuntimeException("旧密码不正确");
        }
        user.setPassword(passwordEncoder.encode(req.getNewPassword()));
        userMapper.updateById(user);
    }

    @Override
    public String getPasskeyByUserId(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null || user.getPasskey() == null) {
            throw new BusinessException("用户不存在或未生成 passkey");
        }
        return user.getPasskey();
    }
    @Autowired
    private UserMoneyMapper userMoneyMapper;

    @Override
    public ValuesInfoDTO getValuesInfo(Long userId) {
        UserMoney userMoney = userMoneyMapper.selectById(userId);

        if (userMoney == null) {
            ValuesInfoDTO dto = new ValuesInfoDTO();
            dto.setUserId(userId);
            dto.setPoints(0.0);
            dto.setTickets(0.0);
            dto.setMagicValue(0.0);
            return dto;
        }

        ValuesInfoDTO dto = new ValuesInfoDTO();
        dto.setUserId(userId);
        dto.setPoints(userMoney.getPoint());
        dto.setTickets(userMoney.getTicket());
        dto.setMagicValue(userMoney.getMagicvalue());
        return dto;
    }
}